/**
 *
 * The MIT License
 *
 * Copyright (c) Valerio Proietti, Tom Occhino All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 * This source code is what Noritaka Horio(http://sharedhat.com) modified it
 * based on snippely.database.js of snippely(http://code.google.com/p/snippely/). 
 * 
 * @author Valerio Proietti (http://mad4milk.net)
 * @author Tom Occhino (http://tomocchino.com)
 * @author Noritaka Horio (http://sharedhat.com)
 * @license The MIT License
 * @version $Rev: 187 $ $Date: 2009-11-08 03:25:12 +0000 (Sun, 08 Nov 2009) $
 * @see http://mootools.net
 * @see http://code.google.com/p/snippely/
 */

var Clock;
if (!Clock) Clock = {};

Clock.Database = new Class({

	Implements: [Events, Options],
	
	options: {/*
		onOpen: $empty,
		onError: $empty,*/
		filename: 'application.db'
	},
	
	initialize: function(options){
		this.setOptions(options);
		
		this.connection = new air.SQLConnection();
		this.connection.addEventListener('open', this.onOpen.bind(this));
		this.connection.addEventListener('error', this.onError);
		
		this.dbFile = air.File.applicationStorageDirectory.resolvePath(this.options.filename);
		this.isInitialize = this.dbFile.exists;
		this.connection.openAsync(this.dbFile);
	},
	
	create: function(callback){
		var task = "CREATE TABLE IF NOT EXISTS task ("
		+ "\"id\" INTEGER PRIMARY KEY  NOT NULL,"
		+ "\"type\" VARCHAR,"
		+ "\"value\" VARCHAR,"
		+ "\"plugin\" VARCHAR,"
		+ "\"active\" INTEGER NOT NULL DEFAULT 0,"
		+ "\"create_time\" DATETIME,"
		+ "\"update_time\" DATETIME"
		+ ");";

		var configuration = "CREATE TABLE IF NOT EXISTS configuration ("
		+ "\"id\" INTEGER PRIMARY KEY  NOT NULL,"
		+ "\"type\" VARCHAR,"
		+ "\"value\" VARCHAR"
		+ ");";

		var defaultTask = "INSERT INTO task"
		+ "(type,value,plugin,active,create_time) VALUES "
		+ "('periodical',60,'processing',1,100);";

		var defaultConfiguration = "INSERT INTO configuration"
		+ "(type,value) VALUES ('theme','default');";

		var self = this;
		var queries = [task, configuration, defaultTask, defaultConfiguration];
		(function(){
			self.execute(queries.shift(), (queries.length ? arguments.callee : callback));
		})();
	},
	
	execute: function(){
		var args = Array.link(arguments, {sql: String.type, callback: Function.type, params: Object.type});
		var sql = args.sql, callback = args.callback || $empty, params = args.params || {};
		
		var statement = new air.SQLStatement();
		statement.sqlConnection = this.connection;
		statement.text = sql;
		
		$each(params, function(value, key){
			statement.parameters[":" + key] = value;
		});
		
		statement.addEventListener(air.SQLEvent.RESULT, function(){ callback(statement.getResult(), event); });
		statement.addEventListener(air.SQLErrorEvent.ERROR, this.onError);
		statement.execute();
	},
	
	// Callbacks
	
	onOpen: function(event){
		air.trace("database created / loaded");
		(this.isInitialize) ? this.fireEvent("open") : this.create(this.fireEvent.bind(this, 'onOpen'));
	},
	
	onError: function(event){
		air.trace("Error message:", event.error.message);
		air.trace("Details:", event.error.details);
	},
	
	// Nuke the database
	
	nuke: function(){
		["task", "config"].each(function(table){
			this.execute("DROP TABLE " + table);
		}, this);
	}
	
});